# coding: utf-8

import json
from datetime import datetime, timedelta

from common.constant import DEMAND_WINNER_QUEUE, BidQueueStatus
from common.demand_util import gen_renewable_demand, \
    demand_complete
from common.models import (
    model_factory, DemandStatus, ParticStatus, FollowType
)
from common.producer import Producer
from common.schedule.demand_utils import bid_limit, current_bid_users, \
    update_not_contact, clear_cache, unbind_virtual_number
from common.schedule.opc_celery import celery_app
from common.utils import DB
from common.bid_notify.message import MessageNotify


@celery_app.task(name='demand_assign_winner_task')
def demand_assign_winner_task(
        demand_id,
        published_count):
    """
    首次竞价分配中标人任务
    1、根据中标人数修改订单状态
       a、人数足够则修改为竞价结束
       b、人数不足则直接进入二次竞价（一口价）
    2、往中标消费者发送消息
    :return:
    """
    with DB() as session:
        winners = current_bid_users(session, demand_id, published_count)

        if winners:
            # 发送消息到消费者
            partic_ids = [each.id for each in winners]
            Producer(DEMAND_WINNER_QUEUE).send(
                json.dumps(dict(
                    func='assign_winner',
                    args=(),
                    kwargs=dict(
                        partic_ids=partic_ids,
                        demand_id=demand_id,
                        published_count=published_count
                    )
                ))
            )
        else:
            demand = model_factory.demand.get_by_id(session, demand_id)
            demand_complete(demand)
            gen_renewable_demand(session, demand)


@celery_app.task(name='update_demand_delay_task')
def update_demand_delay_task(demand_id, status, new_status):
    """
    create by ld_wu 2018-01-25
    更新项目状态
    :return:
    """
    with DB() as session:
        demand = model_factory.demand.get_by_args(
            session,
            id=demand_id,
            status=status
        )
        if demand:
            demand.status = new_status


@celery_app.task(
    name='demand_assign_status_task',
    bind=True,
    max_retries=3,
    default_retry_delay=5)
def demand_assign_status_task(
        self,
        demand_id,
        published_count):
    """
    create by ld_wu 2018-01-24
    项目发布5分钟后，项目状态改为分配中，3秒后进入中标流程
    为了避免在5分钟的时候有人竞价了，打乱了中标流程
    :return:
    """
    now = datetime.utcnow()
    print('项目:{} 进入5秒分配中'.format(demand_id))
    try:

        with DB() as session:
            demand = model_factory.demand.get_by_args(
                session,
                id=demand_id,
                status=DemandStatus.ONGOING.value
            )
            if demand:
                demand.status = DemandStatus.ASSIGN.value
            params = (
                demand_id,
                published_count
            )

            demand_assign_winner_task.apply_async(
                params,
                eta=now + timedelta(seconds=3),
                expires=now + timedelta(seconds=60 * 2)
            )
    except Exception as exc:
        print(exc)
        self.retry(exc=exc, expires=now + timedelta(seconds=60 * 2))


@celery_app.task(name='robot_delay_update_status')
def robot_delay_update_status(demand_id, partic_id, contact_seconds):
    """
    create by ld_wu 2018-01-25
    自动竞价延时更新竞标状态（模拟通话成功）
    机器人自动置为放弃跟进  2018-08-01
    """
    with DB() as session:
        partic = model_factory.partic.get_by_id(
            session,
            partic_id
        )
        if partic:
            partic.status = ParticStatus.SUCCEED.value
            partic.contact_state = 1
            partic.contact_seconds = contact_seconds
            partic.follow_type = FollowType.GIVE_UP.value

        queue = model_factory.bid_user_queues.get_by_args(
            session,
            partic_id=partic_id
        )
        if queue:
            queue.status = BidQueueStatus.CALLED
    clear_cache(demand_id)


@celery_app.task(
    name='winner_handle_task',
    bind=True,
    max_retries=3,
    default_retry_delay=5)
def winner_handle_task(self, partic_id, demand_id, published_count):
    """
    create by ld_wu 2018-03-20
    抢单中标任务
    :return:
    """

    with DB() as session:
        demand = model_factory.demand.get_by_id(session, demand_id)
        print('winner_handler_task demand: {} partic_id: {}'.format(demand_id, partic_id))
        if partic_id:
            owner = model_factory.user.get_by_id(session, demand.uid)
            partic = session.query(model_factory.partic).filter(
                model_factory.partic.id == partic_id
            ).first()
            if partic and partic.status in (
                ParticStatus.NOT_CONTACT.value, ParticStatus.BALANCE_NOT_ENOUGH.value
            ):
                # 待充值 --> 超时未联系
                print('demand{} time_out {}'.format(demand_id, partic.id))
                # 扣除抢单惩罚
                update_not_contact(session, partic, demand)
                partic.status = ParticStatus.TIMEOUT_NOT_CONTACT.value
                # 退单以后进入回收站
                gen_renewable_demand(session, demand)
                # 解绑虚拟号
                unbind_virtual_number(
                    demand_id, partic.supplier_id, owner.mobile, session
                )

                queue = model_factory.bid_user_queues.get_by_args(
                    session,
                    partic_id=partic_id
                )
                if queue:
                    queue.status = BidQueueStatus.TIME_OUT

    clear_cache(demand_id)


@celery_app.task(
    name='bronze_winner_handle_task',
    bind=True,
    max_retries=3,
    default_retry_delay=5)
def bronze_winner_handle_task(self, partic_id, demand_id):
    """
    create by ld_wu 2018-04-11
    铜牌超时未联系任务
    :return:
    """
    with DB() as session:
        demand = model_factory.demand.get_by_id(session, demand_id)
        print('winner_handler_task demand:{} partic_ids{}'.format(demand_id, partic_id))
        owner = model_factory.user.get_by_id(session, demand.uid)
        partic = model_factory.partic.get_by_id(session, partic_id)
        # 未联系
        if partic.status in (ParticStatus.NOT_CONTACT.value, ParticStatus.BALANCE_NOT_ENOUGH.value):
            # 待充值 --> 超时未联系
            print('demand{} time_out {}'.format(demand_id, partic.id))
            # 扣除抢单惩罚
            update_not_contact(session, partic, demand)
            partic.status = ParticStatus.TIMEOUT_NOT_CONTACT.value
            gen_renewable_demand(session, demand)
            # 解绑虚拟号
            unbind_virtual_number(
                demand_id, partic.supplier_id, owner.mobile, session
            )


@celery_app.task(name='bid_winner_call_notify')
def bid_winner_call_notify(partic_id, mobile):
    """
    created by chenhj at 2018/6/12
    5分钟后, 检查用户是否已经拨打电话, 若尚未, 则再推送通知提醒用户
    """
    with DB() as session:
        partic = model_factory.partic.get_by_id(session, partic_id)
        demand = model_factory.demand.get_by_id(session, partic.demand_id)
        if partic.status in (
            ParticStatus.NOT_CONTACT.value, ParticStatus.BALANCE_NOT_ENOUGH.value
        ):
            MessageNotify.bid_winner_call_notify(session, partic, demand, mobile)

